package fem2.material;

import inf.jlinalg.IVector;

import java.util.ArrayList;

import org.junit.Test;

import fem2.AbstractStructuralStaticDemo;
import fem2.Constraint;
import fem2.Debugger;
import fem2.Element;
import fem2.Face;
import fem2.MaterialModel;
import fem2.Mesh;
import fem2.MeshPart;
import fem2.MeshUtilities;
import fem2.Model;
import fem2.Node;
import fem2.Patch;
import fem2.PatchManager;
import fem2.PatchTestT3;
import fem2.analysis.Analysis;
import fem2.analysis.LinearStaticAnalysis;
import fem2.element.StructuralElement;
import fem2.enu.EchoLevelType;
import fem2.enu.State;

public class PatchTestSPRStressRecovery extends AbstractStructuralStaticDemo {

	@Override
	public Mesh createMesh() {
		return new PatchTestT3(0).createMesh();
	}

	@Override
	public Model createConditions(Model m) {
		return m;
	}

	@Override
	public MaterialModel createMaterial(Model m) {
		double E = 2;
		double nu = 0.3;
		double t = 1.0;
		State ss = State.PLANE_STRESS;
		MaterialModel mm = new SPRrecoveryMM(m, new StVenantKirchhoffMM(E, nu, t, 0, ss));
		return mm;
	}

	@Override
	public Element createElement(MeshPart mp, MaterialModel mm) {
		return new StructuralElement(mp, mm);
	}

	@Test
	public void test1() {
		Model m = createModel();
		Mesh mesh = m.getMesh();

		double du = 2;
		Constraint c1 = new Constraint(false, false);
		c1.setValue(0, du);
		Constraint c2 = new Constraint(false, true);
		c2.setValue(0, du);

		mesh.setConstraint(c2, MeshUtilities.seekNodesOnSurface(mesh, 1, 0, -1));
		MeshUtilities.seekNode(mesh, 1, 0).setConstraint(c1);

		Analysis an = new LinearStaticAnalysis(m);
		an.getStrategy().setEchoLevel(EchoLevelType.OUTPUT, EchoLevelType.AUX1);
		an.run();

		SPRrecoveryMM mm = (SPRrecoveryMM) ((StructuralElement) m.getElement(0))
				.getMaterialModel();

		Debugger.watch("Patches information:s");
		PatchManager pm = mm.getPatchManager();
		for (int i = 0; i < mesh.countNodes(); i++) {
			ArrayList<Patch> patchList = pm.getPatch(mesh.getNode(i));
			for (Patch p : patchList) {
				int numMeshPart = p.countMeshPart();
				for (int j = 0; j < numMeshPart; j++) {
					Debugger.watch(p.getMeshPart(j).toString());
				}
				Debugger.watch("--------------");
			}
		}

		for (int i = 0; i < m.countElements(); i++) {
			StructuralElement se = (StructuralElement) m.getElement(i);
			int ng = se.getNumIntegrationPoints();
			for (int j = 0; j < ng; j++) {
				Debugger.watch("real stress " + i + ", " + j + " = ", se.getStress(j));
			}
		}
		for (int i = 0; i < mesh.countNodes(); i++) {
			IVector s = mm.computeRecoverStress(mesh.getNode(i));
			Debugger.watch("recover stress " + i + " =", s);
		}
	}

	@Test
	public void probeShapeFunction() {
		Node n1 = new Node(0, 0);
		Node n2 = new Node(1, 0);
		Node n3 = new Node(0, 1);

		Face f = new Face(n1, n2, n3);

		Debugger.watch(f.valueAt(0, 0));
		Debugger.watch(f.valueAt(1, 0));
		Debugger.watch(f.valueAt(0, 1));
		Debugger.watch(f.valueAt(0, 1));

		Element e = new StructuralElement(f, null);
		
		double[] xi = e.getIntegrationPoint(0);
		Debugger.watch(f.valueAt(xi));
	}
}
